#ifdef UTILTEST

#include <gtest/gtest.h>
#include "util/stdc.h"
#include "util/proper.h"
#include "util/string.h"
#include "util/charset.h"
#include "util/json.h"
#include "util/queue.h"
#include "util/pool.h"
#include "util/iconv.h"
#include "util/time.h"
#include "util/pinger.h"
#include "util/misc.h"
#include "sip9/message.h"
#include "third/mysql.h"

TEST(UtilTest, TypeTest)
{
	static_assert(sizeof(u64)==8, "size u64 invalid");
	static_assert(sizeof(u32)==4, "size u32 invalid");
	static_assert(sizeof(u16)==2, "size u16 invalid");

	static_assert(sizeof(i64)==8, "size i64 invalid");
	static_assert(sizeof(i32)==4, "size i32 invalid");
	static_assert(sizeof(i16)==2, "size i16 invalid");

	static_assert(sizeof(long)==4, "size long invalid");
	static_assert(sizeof(short)==2, "size short invalid");
	static_assert(sizeof(bool)==1, "size bool invalid");

	SUCCEED();
}

TEST(UtilTest, ProperTest)
{
    util::Proper proper;

    ASSERT_EQ(0, proper.load("proper.ini"));

    ASSERT_EQ(111, proper.get("set1", -1));
    ASSERT_EQ(222, proper.get("set2", -1));
    ASSERT_EQ(333, proper.get("set3", -1));
    ASSERT_EQ(444, proper.get("set4", -1));
    ASSERT_EQ(-1, proper.get("set5", -1));
    ASSERT_EQ(0, proper.get("set5", 0));

	SUCCEED();
}

TEST(UtilTest, StringTest)
{
    ASSERT_EQ("", util::ltrim(""));
    ASSERT_EQ("", util::ltrim(" "));
    ASSERT_EQ("", util::ltrim(" \t"));
    ASSERT_EQ("", util::ltrim("\t "));
    ASSERT_EQ("", util::ltrim(" \r \n"));

    ASSERT_EQ("abc", util::ltrim("abc"));
    ASSERT_EQ("abc", util::ltrim(" abc"));
    ASSERT_EQ("abc", util::ltrim(" \tabc"));
    ASSERT_EQ("abc", util::ltrim("\t abc"));
    ASSERT_EQ("abc", util::ltrim(" \t \tabc"));

    ASSERT_EQ("", util::rtrim(""));
    ASSERT_EQ("", util::rtrim(" "));
    ASSERT_EQ("", util::rtrim(" \t"));
    ASSERT_EQ("", util::rtrim("\t "));
    ASSERT_EQ("", util::rtrim(" \r \n"));

    ASSERT_EQ("abc", util::rtrim("abc"));
    ASSERT_EQ("abc", util::rtrim("abc "));
    ASSERT_EQ("abc", util::rtrim("abc\t"));
    ASSERT_EQ("abc", util::rtrim("abc\t "));
    ASSERT_EQ("abc", util::rtrim("abc \t \t"));

    ASSERT_EQ("", util::trim(""));
    ASSERT_EQ("", util::trim(" "));
    ASSERT_EQ("", util::trim(" \t"));
    ASSERT_EQ("", util::trim("\t "));
    ASSERT_EQ("", util::trim(" \r \n"));

    ASSERT_EQ("abc", util::trim("abc"));
    ASSERT_EQ("abc", util::trim(" abc"));
    ASSERT_EQ("abc", util::trim("abc\t"));
    ASSERT_EQ("abc", util::trim(" \t abc \t "));

    std::vector<string> vec;
    vec = util::split("12, 34 \t , 567,8,9,\t 0", ',');
    ASSERT_EQ(6, vec.size());
    ASSERT_EQ("12", vec[0]);
    ASSERT_EQ("34", vec[1]);
    ASSERT_EQ("567", vec[2]);
    ASSERT_EQ("8", vec[3]);
    ASSERT_EQ("9", vec[4]);
    ASSERT_EQ("0", vec[5]);

    vec = util::split("\t 1,234 , \t\t\t567,,89, 0,", ',');
    ASSERT_EQ(7, vec.size());
    ASSERT_EQ("1", vec[0]);
    ASSERT_EQ("234", vec[1]);
    ASSERT_EQ("567", vec[2]);
    ASSERT_EQ("", vec[3]);
    ASSERT_EQ("89", vec[4]);
    ASSERT_EQ("0", vec[5]);
	ASSERT_EQ("", vec[6]);

    vec = util::split("", ',');
    ASSERT_EQ(1, vec.size());
	
    vec = util::split("x", ',');
    ASSERT_EQ(1, vec.size());
    ASSERT_EQ("x", vec[0]);

    vec = util::split(",", ',');
    ASSERT_EQ(2, vec.size());
    ASSERT_EQ("", vec[0]);
    ASSERT_EQ("", vec[1]);

    vec = util::split("x,", ',');
    ASSERT_EQ(2, vec.size());
    ASSERT_EQ("x", vec[0]);
    ASSERT_EQ("", vec[1]);

    vec = util::split(",x", ',');
    ASSERT_EQ(2, vec.size());
    ASSERT_EQ("", vec[0]);
    ASSERT_EQ("x", vec[1]);

    ASSERT_EQ("true", util::to_string(true));
    ASSERT_EQ("false", util::to_string(false));

    ASSERT_EQ("900150983cd24fb0d6963f7d28e17f72", util::to_md5("abc"));
    ASSERT_EQ("40bd001563085fc35165329ea1ff5c5ecbdbbeef", util::to_sha1("123"));

	SUCCEED();
}

TEST(UtilTest, CharSetTest)
{
    util::CharSet cset("aB3");
    ASSERT_TRUE(cset.is_set('a'));
    ASSERT_TRUE(cset.is_set('B'));
    ASSERT_TRUE(cset.is_set('3'));
    ASSERT_FALSE(cset.is_set('b'));
    ASSERT_FALSE(cset.is_set('C'));
    ASSERT_FALSE(cset.is_set('4'));

    cset.set("bC4", 3);
    ASSERT_TRUE(cset.is_set('a'));
    ASSERT_TRUE(cset.is_set('B'));
    ASSERT_TRUE(cset.is_set('3'));
    ASSERT_TRUE(cset.is_set('b'));
    ASSERT_TRUE(cset.is_set('C'));
    ASSERT_TRUE(cset.is_set('4'));

	SUCCEED();
}

char json_msg_001[] =
"{\"bindings\": [\
{\"ircEvent\": \"PRIVMSG\", \"method\": \"newURI\", \"regex\": \"^http://.*\"},\
{\"ircEvent\": \"PRIVMSG\", \"method\": \"deleteURI\", \"regex\": \"^delete.*\"},\
{\"ircEvent\": \"PRIVMSG\", \"method\": \"randomURI\", \"regex\": \"^random.*\"}]}";

TEST(UtilTest, JsonTest)
{
    util::Json json;
    string str1, str2;

    ASSERT_EQ(strlen(json_msg_001), json.deserialize(json_msg_001));
    str1 = json.serialize();

    ASSERT_EQ(string("PRIVMSG"), json["bindings"][0]["ircEvent"].get_string());
    ASSERT_EQ(string("deleteURI"), json["bindings"][1]["method"].get_string());
    ASSERT_EQ(string("^random.*"), json["bindings"][2]["regex"].get_string());

	ASSERT_EQ(str1.length(), json.deserialize(str1));
    str2 = json.serialize();
    ASSERT_EQ(str1, str2);

    json.clear();
    json["i32"] = i32(100);
    json["i64"] = i64(200);
    json["f32"] = f32(300.0);
    json["f64"] = f64(400.0);
    json["str"] = "val";
    json["vec"][0] = "sub0";
    json["vec"][1] = "sub1";
    json["vec"][2] = i32(500);
    json["map"]["key1"] = "val1";
    json["map"]["key2"] = "val2";
    json["map"]["key3"] = i32(600);

    ASSERT_EQ(100, json["i32"].get_i32());
    ASSERT_EQ(200, json["i64"].get_i64());
    ASSERT_EQ(300.0, json["f32"].get_f32());
    ASSERT_EQ(400.0, json["f64"].get_f64());
    ASSERT_EQ(string("val"), json["str"].get_string());

    ASSERT_EQ(string("sub0"), json["vec"][0].get_string());
    ASSERT_EQ(string("sub1"), json["vec"][1].get_string());
    ASSERT_EQ(500, json["vec"][2].get_i32());

    ASSERT_EQ(string("val1"), json["map"]["key1"].get_string());
    ASSERT_EQ(string("val2"), json["map"]["key2"].get_string());
    ASSERT_EQ(600, json["map"]["key3"].get_i32());

	SUCCEED();
}

TEST(UtilTest, PingerTest)
{
	util::Pinger pinger;
	int ttl=0, rtt=0;

	ASSERT_EQ(0, pinger.ping("8.8.8.8", ttl, rtt));

	SUCCEED();
}

TEST(UtilTest, TimeTest)
{
	util::sleep(10);

	SUCCEED();
}

char sip_msg_001[] =
"REGISTER sips:ss2.biloxi.example.com SIP/2.0\r\n\
Via: SIP/2.0/TLS client.biloxi.example.com:5061;branch=z9hG4bKnashds7\r\n\
Max-Forwards: 70\r\n\
From: Bob <sips:bob@biloxi.example.com>;tag=a73kszlfl\r\n\
To: Bob <sips:bob@biloxi.example.com>\r\n\
Call-ID: 1j9FpLxk3uxtm8tn@biloxi.example.com\r\n\
CSeq: 1 REGISTER\r\n\
Contact: <sips:bob@client.biloxi.example.com>\r\n\
Content-Length: 0\r\n\
\r\n";

char sip_msg_002[] =
"SIP/2.0 401 Unauthorized\r\n\
Via: SIP/2.0/TLS client.biloxi.example.com:5061;branch=z9hG4bKnashds7;received=192.0.2.201\r\n\
From: Bob <sips:bob@biloxi.example.com>;tag=a73kszlfl\r\n\
To: Bob <sips:bob@biloxi.example.com>;tag=1410948204\r\n\
Call-ID: 1j9FpLxk3uxtm8tn@biloxi.example.com\r\n\
CSeq: 1 REGISTER\r\n\
WWW-Authenticate: Digest realm=\"atlanta.example.com\", qop=\"auth\", nonce=\"ea9c8e88df84f1cec4341ae6cbe5a359\", opaque=\"\", stale=FALSE, algorithm=MD5\r\n\
Content-Length: 0\r\n\
\r\n";

char sip_msg_003[] =
"REGISTER sips:ss2.biloxi.example.com SIP/2.0\r\n\
Via: SIP/2.0/TLS client.biloxi.example.com:5061;branch=z9hG4bKnashd92\r\n\
Max-Forwards: 70\r\n\
From: Bob <sips:bob@biloxi.example.com>;tag=ja743ks76zlflH\r\n\
To: Bob <sips:bob@biloxi.example.com>\r\n\
Call-ID: 1j9FpLxk3uxtm8tn@biloxi.example.com\r\n\
CSeq: 2 REGISTER\r\n\
Contact: <sips:bob@client.biloxi.example.com>\r\n\
Authorization: Digest username=\"bob\", realm=\"atlanta.example.com\", nonce=\"ea9c8e88df84f1cec4341ae6cbe5a359\", opaque=\"\", uri=\"sips:ss2.biloxi.example.com\", response=\"dfe56131d1958046689d83306477ecc\"\r\n\
Content-Length: 0\r\n\
\r\n";

char sip_msg_004[] =
"SIP/2.0 200 OK\r\n\
Via: SIP/2.0/TLS client.biloxi.example.com:5061;branch=z9hG4bKnashd92;received=192.0.2.201\r\n\
From: Bob <sips:bob@biloxi.example.com>;tag=ja743ks76zlflH\r\n\
To: Bob <sips:bob@biloxi.example.com>;tag=37GkEhwl6\r\n\
Call-ID: 1j9FpLxk3uxtm8tn@biloxi.example.com\r\n\
CSeq: 2 REGISTER\r\n\
Contact: <sips:bob@client.biloxi.example.com>;expires=3600\r\n\
Content-Length: 0\r\n\
\r\n";

char sip_msg_005[] =
"INVITE sip:bob@biloxi.example.com SIP/2.0\r\n\
Via: SIP/2.0/TCP client.atlanta.example.com:5060;branch=z9hG4bK74bf9\r\n\
Max-Forwards: 70\r\n\
From: Alice <sip:alice@atlanta.example.com>;tag=9fxced76sl\r\n\
To: Bob <sip:bob@biloxi.example.com>\r\n\
Call-ID: 3848276298220188511@atlanta.example.com\r\n\
CSeq: 1 INVITE\r\n\
Contact: <sip:alice@client.atlanta.example.com;transport=tcp>\r\n\
Content-Type: application/sdp\r\n\
Content-Length: 151\r\n\
\r\n\
v=0\r\n\
o=alice 2890844526 2890844526 IN IP4 client.atlanta.example.com\r\n\
s=-\r\n\
c=IN IP4 192.0.2.101\r\n\
t=0 0\r\n\
m=audio 49172 RTP/AVP 0\r\n\
a=rtpmap:0 PCMU/8000\r\n";

char sip_msg_006[] =
"SIP/2.0 180 Ringing\r\n\
Via: SIP/2.0/TCP client.atlanta.example.com:5060;branch=z9hG4bK74bf9;received=192.0.2.101\r\n\
From: Alice <sip:alice@atlanta.example.com>;tag=9fxced76sl\r\n\
To: Bob <sip:bob@biloxi.example.com>;tag=8321234356\r\n\
Call-ID: 3848276298220188511@atlanta.example.com\r\n\
CSeq: 1 INVITE\r\n\
Contact: <sip:bob@client.biloxi.example.com;transport=tcp>\r\n\
Content-Length: 0\r\n\
\r\n";

char sip_msg_007[] =
"SIP/2.0 200 OK\r\n\
Via: SIP/2.0/TCP client.atlanta.example.com:5060;branch=z9hG4bK74bf9;received=192.0.2.101\r\n\
From: Alice <sip:alice@atlanta.example.com>;tag=9fxced76sl\r\n\
To: Bob <sip:bob@biloxi.example.com>;tag=8321234356\r\n\
Call-ID: 3848276298220188511@atlanta.example.com\r\n\
CSeq: 1 INVITE\r\n\
Contact: <sip:bob@client.biloxi.example.com;transport=tcp>\r\n\
Content-Type: application/sdp\r\n\
Content-Length: 147\r\n\
\r\n\
v=0\r\n\
o=bob 2890844527 2890844527 IN IP4 client.biloxi.example.com\r\n\
s=-\r\n\
c=IN IP4 192.0.2.201\r\n\
t=0 0\r\n\
m=audio 3456 RTP/AVP 0\r\n\
a=rtpmap:0 PCMU/8000\r\n";

char sip_msg_008[] =
"ACK sip:bob@client.biloxi.example.com SIP/2.0\r\n\
Via: SIP/2.0/TCP client.atlanta.example.com:5060;branch=z9hG4bK74bd5\r\n\
Max-Forwards: 70\r\n\
From: Alice <sip:alice@atlanta.example.com>;tag=9fxced76sl\r\n\
To: Bob <sip:bob@biloxi.example.com>;tag=8321234356\r\n\
Call-ID: 3848276298220188511@atlanta.example.com\r\n\
CSeq: 1 ACK\r\n\
Content-Length: 0\r\n\
\r\n";

char sip_msg_009[] =
"BYE sip:alice@client.atlanta.example.com SIP/2.0\r\n\
Via: SIP/2.0/TCP client.biloxi.example.com:5060;branch=z9hG4bKnashds7\r\n\
Max-Forwards: 70\r\n\
From: Bob <sip:bob@biloxi.example.com>;tag=8321234356\r\n\
To: Alice <sip:alice@atlanta.example.com>;tag=9fxced76sl\r\n\
Call-ID: 3848276298220188511@atlanta.example.com\r\n\
CSeq: 1 BYE\r\n\
Content-Length: 0\r\n\
\r\n";

char sip_msg_010[] =
"SIP/2.0 200 OK\r\n\
Via: SIP/2.0/TCP client.biloxi.example.com:5060;branch=z9hG4bKnashds7;received=192.0.2.201\r\n\
From: Bob <sip:bob@biloxi.example.com>;tag=8321234356\r\n\
To: Alice <sip:alice@atlanta.example.com>;tag=9fxced76sl\r\n\
Call-ID: 3848276298220188511@atlanta.example.com\r\n\
CSeq: 1 BYE\r\n\
Content-Length: 0\r\n\
\r\n";

// The following cases come from RFC 4475 SIP Torture Test Messages

char sip_msg_011[] =
"INVITE sip:vivekg@chair-dnrc.example.com;unknownparam SIP/2.0\r\n\
TO :\r\n\
 sip:vivekg@chair-dnrc.example.com ;   tag    = 1918181833n\r\n\
from   : \"J Rosenberg \\\\\\\"\"       <sip:jdrosen@example.com>\r\n\
  ;\r\n\
  tag = 98asjd8\r\n\
MaX-fOrWaRdS: 0068\r\n\
Call-ID: wsinv.ndaksdj@192.0.2.1\r\n\
Content-Length   : 150\r\n\
cseq: 0009\r\n\
  INVITE\r\n\
Via  : SIP  /   2.0\r\n\
 /UDP\r\n\
    192.0.2.2;branch=390skdjuw\r\n\
s :\r\n\
NewFangledHeader:   newfangled value\r\n\
 continued newfangled value\r\n\
UnknownHeaderWithUnusualValue: ;;,,;;,;\r\n\
Content-Type: application/sdp\r\n\
Route:\r\n\
 <sip:services.example.com;lr;unknownwith=value;unknown-no-value>\r\n\
v:  SIP  / 2.0  / TCP     spindle.example.com   ;\r\n\
  branch  =   z9hG4bK9ikj8  ,\r\n\
 SIP  /    2.0   / UDP  192.168.255.111   ; branch=\r\n\
 z9hG4bK30239\r\n\
m:\"Quoted string \\\"\\\"\" <sip:jdrosen@example.com> ; newparam =\r\n\
      newvalue ;\r\n\
  secondparam ; q = 0.33\r\n\
\r\n\
v=0\r\n\
o=mhandley 29739 7272939 IN IP4 192.0.2.3\r\n\
s=-\r\n\
c=IN IP4 192.0.2.4\r\n\
t=0 0\r\n\
m=audio 49217 RTP/AVP 0 12\r\n\
m=video 3227 RTP/AVP 31\r\n\
a=rtpmap:31 LPC\r\n";

char sip_msg_012[] =
"!interesting-Method0123456789_*+`.%indeed'~ sip:1_unusual.URI~(to-be!sure)&sn't+it$/crazy?,/;;*:&it+has=1,weird!*pas$wo~d_too.(doesn't-it)@example.com SIP/2.0\r\n\
Via: SIP/2.0/TCP host1.example.com;branch=z9hG4bK-.!%66*_+`'~\r\n\
To: \"BEL:\\\x07 NUL:\\\x00 DEL:\\\x7F\" <sip:1_unusual.URI~(to-be!sure)&isn't+it$/crazy?,/;;*@example.com>\r\n\
From: token1~` token2'+_ token3*%!.- <sip:mundane@example.com>;fromParam''~+*_!.-%=\"\xD1\x80\xD0\xB0\xD0\xB1\xD0\xBE\xD1\x82\xD0\xB0\xD1\x8E\xD1\x89\xD0\xB8\xD0\xB9\";tag=_token~1'+`*%!-.\r\n\
Call-ID: intmeth.word%ZK-!.*_+'@word`~)(><:\\/\"][?}{\r\n\
CSeq: 139122385 !interesting-Method0123456789_*+`.%indeed'~\r\n\
Max-Forwards: 255\r\n\
extensionHeader-!.%*+_`'~:\xEF\xBB\xBF\xE5\xA4\xA7\xE5\x81\x9C\xE9\x9B\xBB\r\n\
Content-Length: 0\r\n\
\r\n";

char sip_msg_013[] =
"INVITE sip:sips%3Auser%40example.com@example.net SIP/2.0\r\n\
To: sip:%75se%72@example.com\r\n\
From: <sip:I%20have%20spaces@example.net>;tag=938\r\n\
Max-Forwards: 87\r\n\
i: esc01.239409asdfakjkn23onasd0-3234\r\n\
CSeq: 234234 INVITE\r\n\
Via: SIP/2.0/UDP host5.example.net;branch=z9hG4bKkdjuw\r\n\
C: application/sdp\r\n\
Contact:\r\n\
  <sip:cal%6Cer@host5.example.net;%6C%72;n%61me=v%61lue%25%34%31>\r\n\
Content-Length: 150\r\n\
\r\n\
v=0\r\n\
o=mhandley 29739 7272939 IN IP4 192.0.2.1\r\n\
s=-\r\n\
c=IN IP4 192.0.2.1\r\n\
t=0 0\r\n\
m=audio 49217 RTP/AVP 0 12\r\n\
m=video 3227 RTP/AVP 31\r\n\
a=rtpmap:31 LPC\r\n";

char sip_msg_014[] =
"REGISTER sip:example.com SIP/2.0\r\n\
To: sip:null-%00-null@example.com\r\n\
From: sip:null-%00-null@example.com;tag=839923423\r\n\
Max-Forwards: 70\r\n\
Call-ID: escnull.39203ndfvkjdasfkq3w4otrq0adsfdfnavd\r\n\
CSeq: 14398234 REGISTER\r\n\
Via: SIP/2.0/UDP host5.example.com;branch=z9hG4bKkdjuw\r\n\
Contact: <sip:%00@host5.example.com>\r\n\
Contact: <sip:%00%00@host5.example.com>\r\n\
L:0\r\n\
\r\n";

char sip_msg_015[] =
"RE%47IST%45R sip:registrar.example.com SIP/2.0\r\n\
To: \"%Z%45\" <sip:resource@example.com>\r\n\
From: \"%Z%45\" <sip:resource@example.com>;tag=f232jadfj23\r\n\
Call-ID: esc02.asdfnqwo34rq23i34jrjasdcnl23nrlknsdf\r\n\
Via: SIP/2.0/TCP host.example.com;branch=z9hG4bK209%fzsnel234\r\n\
CSeq: 29344 RE%47IST%45R\r\n\
Max-Forwards: 70\r\n\
Contact: <sip:alias1@host1.example.com>\r\n\
C%6Fntact: <sip:alias2@host2.example.com>\r\n\
Contact: <sip:alias3@host3.example.com>\r\n\
l: 0\r\n\
\r\n";

char sip_msg_016[] =
"OPTIONS sip:user@example.com SIP/2.0\r\n\
To: sip:user@example.com\r\n\
From: caller<sip:caller@example.com>;tag=323\r\n\
Max-Forwards: 70\r\n\
Call-ID: lwsdisp.1234abcd@funky.example.com\r\n\
CSeq: 60 OPTIONS\r\n\
Via: SIP/2.0/UDP funky.example.com;branch=z9hG4bKkdjuw\r\n\
l: 0\r\n\
\r\n";

char sip_msg_017[] =
"INVITE sip:user@example.com SIP/2.0\r\n\
To: \"I have a user name of extremeextremeextremeextremeextremeextremeextremeextremeextremeextreme proportion\"<sip:user@example.com:6000;unknownparam1=verylonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglongvalue;longparamnamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamename=shortvalue;verylonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglongParameterNameWithNoValue>\r\n\
F: sip:amazinglylongcallernameamazinglylongcallernameamazinglylongcallernameamazinglylongcallernameamazinglylongcallername@example.net;tag=12982982982982982982982982982982982982982982982982982982982982982982982982982982982982982982982982982982982982982982982982982982982982982982982982982982424;unknownheaderparamnamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamename=unknowheaderparamvaluevaluevaluevaluevaluevaluevaluevaluevaluevaluevaluevaluevaluevaluevalue;unknownValuelessparamnameparamnameparamnameparamnameparamnameparamnameparamnameparamnameparamnameparamname\r\n\
Call-ID: longreq.onereallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallylongcallid\r\n\
CSeq: 3882340 INVITE\r\n\
Unknown-LongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLong-Name: unknown-longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong-value; unknown-longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong-parameter-name = unknown-longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong-parameter-value\r\n\
Via: SIP/2.0/TCP sip33.example.com\r\n\
v: SIP/2.0/TCP sip32.example.com\r\n\
V: SIP/2.0/TCP sip31.example.com\r\n\
Via: SIP/2.0/TCP sip30.example.com\r\n\
ViA: SIP/2.0/TCP sip29.example.com\r\n\
VIa: SIP/2.0/TCP sip28.example.com\r\n\
VIA: SIP/2.0/TCP sip27.example.com\r\n\
via: SIP/2.0/TCP sip26.example.com\r\n\
viA: SIP/2.0/TCP sip25.example.com\r\n\
vIa: SIP/2.0/TCP sip24.example.com\r\n\
vIA: SIP/2.0/TCP sip23.example.com\r\n\
V :  SIP/2.0/TCP sip22.example.com\r\n\
v :  SIP/2.0/TCP sip21.example.com\r\n\
V  : SIP/2.0/TCP sip20.example.com\r\n\
v  : SIP/2.0/TCP sip19.example.com\r\n\
Via : SIP/2.0/TCP sip18.example.com\r\n\
Via  : SIP/2.0/TCP sip17.example.com\r\n\
Via: SIP/2.0/TCP sip16.example.com\r\n\
Via: SIP/2.0/TCP sip15.example.com\r\n\
Via: SIP/2.0/TCP sip14.example.com\r\n\
Via: SIP/2.0/TCP sip13.example.com\r\n\
Via: SIP/2.0/TCP sip12.example.com\r\n\
Via: SIP/2.0/TCP sip11.example.com\r\n\
Via: SIP/2.0/TCP sip10.example.com\r\n\
Via: SIP/2.0/TCP sip9.example.com\r\n\
Via: SIP/2.0/TCP sip8.example.com\r\n\
Via: SIP/2.0/TCP sip7.example.com\r\n\
Via: SIP/2.0/TCP sip6.example.com\r\n\
Via: SIP/2.0/TCP sip5.example.com\r\n\
Via: SIP/2.0/TCP sip4.example.com\r\n\
Via: SIP/2.0/TCP sip3.example.com\r\n\
Via: SIP/2.0/TCP sip2.example.com\r\n\
Via: SIP/2.0/TCP sip1.example.com\r\n\
Via: SIP/2.0/TCP host.example.com;received=192.0.2.5;branch=verylonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglongbranchvalue\r\n\
Max-Forwards: 70\r\n\
Contact: <sip:amazinglylongcallernameamazinglylongcallernameamazinglylongcallernameamazinglylongcallernameamazinglylongcallername@host5.example.net>\r\n\
Content-Type: application/sdp\r\n\
l: 150\r\n\
\r\n\
v=0\r\n\
o=mhandley 29739 7272939 IN IP4 192.0.2.1\r\n\
s=-\r\n\
c=IN IP4 192.0.2.1\r\n\
t=0 0\r\n\
m=audio 49217 RTP/AVP 0 12\r\n\
m=video 3227 RTP/AVP 31\r\n\
a=rtpmap:31 LPC\r\n";

char sip_msg_018[] =
"REGISTER sip:example.com SIP/2.0\r\n\
To: sip:j.user@example.com\r\n\
From: sip:j.user@example.com;tag=43251j3j324\r\n\
Max-Forwards: 8\r\n\
I: dblreq.0ha0isndaksdj99sdfafnl3lk233412\r\n\
Contact: sip:j.user@host.example.com\r\n\
CSeq: 8 REGISTER\r\n\
Via: SIP/2.0/UDP 192.0.2.125;branch=z9hG4bKkdjuw23492\r\n\
Content-Length: 0\r\n\
\r\n\
INVITE sip:joe@example.com SIP/2.0\r\n\
t: sip:joe@example.com\r\n\
From: sip:caller@example.net;tag=141334\r\n\
Max-Forwards: 8\r\n\
Call-ID: dblreq.0ha0isnda977644900765@192.0.2.15\r\n\
CSeq: 8 INVITE\r\n\
Via: SIP/2.0/UDP 192.0.2.15;branch=z9hG4bKkdjuw380234\r\n\
Content-Type: application/sdp\r\n\
Content-Length: 150\r\n\
\r\n\
v=0\r\n\
o=mhandley 29739 7272939 IN IP4 192.0.2.15\r\n\
s=-\r\n\
c=IN IP4 192.0.2.15\r\n\
t=0 0\r\n\
m=audio 49217 RTP/AVP 0 12\r\n\
m =video 3227 RTP/AVP 31\r\n\
a=rtpmap:31 LPC\r\n";

char sip_msg_019[] =
"OPTIONS sip:user;par=u%40example.net@example.com SIP/2.0\r\n\
To: sip:j_user@example.com\r\n\
From: sip:caller@example.org;tag=33242\r\n\
Max-Forwards: 3\r\n\
Call-ID: semiuri.0ha0isndaksdj\r\n\
CSeq: 8 OPTIONS\r\n\
Accept: application/sdp, application/pkcs7-mime,\r\n\
        multipart/mixed, multipart/signed,\r\n\
        message/sip, message/sipfrag\r\n\
Via: SIP/2.0/UDP 192.0.2.1;branch=z9hG4bKkdjuw\r\n\
l: 0\r\n\
\r\n";

char sip_msg_020[] =
"OPTIONS sip:user@example.com SIP/2.0\r\n\
To: sip:user@example.com\r\n\
From: <sip:caller@example.com>;tag=323\r\n\
Max-Forwards: 70\r\n\
Call-ID:  transports.kijh4akdnaqjkwendsasfdj\r\n\
Accept: application/sdp\r\n\
CSeq: 60 OPTIONS\r\n\
Via: SIP/2.0/UDP t1.example.com;branch=z9hG4bKkdjuw\r\n\
Via: SIP/2.0/SCTP t2.example.com;branch=z9hG4bKklasjdhf\r\n\
Via: SIP/2.0/TLS t3.example.com;branch=z9hG4bK2980unddj\r\n\
Via: SIP/2.0/UNKNOWN t4.example.com;branch=z9hG4bKasd0f3en\r\n\
Via: SIP/2.0/TCP t5.example.com;branch=z9hG4bK0a9idfnee\r\n\
l: 0\r\n\
\r\n";

char sip_msg_021[] =
"MESSAGE sip:kumiko@example.org SIP/2.0\r\n\
Via: SIP/2.0/UDP 127.0.0.1:5070;branch=z9hG4bK-d87543-4dade06d0bdb11ee-1--d87543-;rport\r\n\
Max-Forwards: 70\r\n\
Route: <sip:127.0.0.1:5080>\r\n\
Identity: r5mwreLuyDRYBi/0TiPwEsY3rEVsk/G2WxhgTV1PF7hHuLIK0YWVKZhKv9Mj8UeXqkMVbnVq37CD+813gvYjcBUaZngQmXc9WNZSDNGCzA+fWl9MEUHWIZo1CeJebdY/XlgKeTa0Olvq0rt70Q5jiSfbqMJmQFteeivUhkMWYUA=\r\n\
Contact: <sip:fluffy@127.0.0.1:5070>\r\n\
To: <sip:kumiko@example.org>\r\n\
From: <sip:fluffy@example.com>;tag=2fb0dcc9\r\n\
Call-ID: 3d9485ad0c49859b@Zmx1ZmZ5LW1hYy0xNi5sb2NhbA..\r\n\
CSeq: 1 MESSAGE\r\n\
Content-Transfer-Encoding: binary\r\n\
Content-Type: multipart/mixed;boundary=7a9cbec02ceef655\r\n\
Date: Sat, 15 Oct 2005 04:44:56 GMT\r\n\
User-Agent: SIPimp.org/0.2.5 (curses)\r\n\
Content-Length: 553\r\n\
\r\n\
--7a9cbec02ceef655\r\n\
Content-Type: text/plain\r\n\
Content-Transfer-Encoding: binary\r\n\
\r\n\
Hello\r\n\
--7a9cbec02ceef655\r\n\
Content-Type: application/octet-stream\r\n\
Content-Transfer-Encoding: binary\r\n\
\r\n\
3082015206092A864886F70D010702A08201433082013F0201013109300706052B0E03021A300B06092A864886F70D010701318201203082011C020101307C3070310B3009060355040613025553311330110603550408130A43616C69666F726E69613111300F0603550407130853616E204A6F7365310E300C060355040A1305736970697431293027060355040B13205369706974205465737420436572746966696361746520417574686F7269747902080195007102330113300706052B0E03021A300D06092A864886F70D01010105000481808EF466F948F0522DD2E5978E9D95AAE9F2FE15A06659716292E8DA2AA8D8350A68CEFFAE3CBD2BFF1675DDD5648E593DD64728F26220F7E941749E330D9A15EDABDB93D10C42102E7B7289D29CC0C9AE2EFBC7C0CFF9172F3B027E4FC027E1546DE4B6AA3ABB3E66CCCB5DD6C64B8383149CB8E6FF182D944FE57B65BC99D005\r\n\
--7a9cbec02ceef655--\r\n";

char sip_msg_022[] =
"SIP/2.0 200 = 2**3 * 5**2 \xD0\xBD\xD0\xBE\x20\xD1\x81\xD1\x82\xD0\xBE\x20\xD0\xB4\xD0\xB5\xD0\xB2\xD1\x8F\xD0\xBD\xD0\xBE\xD1\x81\xD1\x82\xD0\xBE\x20\xD0\xB4\xD0\xB5\xD0\xB2\xD1\x8F\xD1\x82\xD1\x8C\x20\x2D\x20\xD0\xBF\xD1\x80\xD0\xBE\xD1\x81\xD1\x82\xD0\xBE\xD0\xB5\r\n\
Via: SIP/2.0/UDP 192.0.2.198;branch=z9hG4bK1324923\r\n\
Call-ID: unreason.1234ksdfak3j2erwedfsASdf\r\n\
CSeq: 35 INVITE\r\n\
From: sip:user@example.com;tag=11141343\r\n\
To: sip:user@example.edu;tag=2229\r\n\
Content-Length: 154\r\n\
Content-Type: application/sdp\r\n\
Contact: <sip:user@host198.example.com>\r\n\
\r\n\
v=0\r\n\
o=mhandley 29739 7272939 IN IP4 192.0.2.198\r\n\
s=-\r\n\
c=IN IP4 192.0.2.198\r\n\
t=0 0\r\n\
m=audio 49217 RTP/AVP 0 12\r\n\
m=video 3227 RTP/AVP 31\r\n\
a=rtpmap:31 LPC\r\n";

char sip_msg_023[] =
"SIP/2.0 100\x20\r\n\
Via: SIP/2.0/UDP 192.0.2.105;branch=z9hG4bK2398ndaoe\r\n\
Call-ID: noreason.asndj203insdf99223ndf\r\n\
CSeq: 35 INVITE\r\n\
From: <sip:user@example.com>;tag=39ansfi3\r\n\
To: <sip:user@example.edu>;tag=902jndnke3\r\n\
Content-Length: 0\r\n\
Contact: <sip:user@host105.example.com>\r\n\
\r\n";

TEST(UtilTest, Sip9Test)
{
    char *sip_msg[] = {sip_msg_001, sip_msg_002, sip_msg_003, sip_msg_004, sip_msg_005,
                       sip_msg_006, sip_msg_007, sip_msg_008, sip_msg_009, sip_msg_010,
                       sip_msg_011, /*sip_msg_012,*/ sip_msg_013, sip_msg_014, /*sip_msg_015,*/
                       sip_msg_016, sip_msg_017, sip_msg_018, sip_msg_019, sip_msg_020,
                       sip_msg_021, sip_msg_022, sip_msg_023};

    int times = 100;

    while (--times)
    {
        for (size_t i=0; i<sizeof(sip_msg)/sizeof(sip_msg[0]); ++i)
        {
            //printf("test sip enc/dec %d start\n", i);
    		//printf("\n\n%s\n", sip_msg[i]);

            sip::Message msg1;
            sip::Message msg2;
            sip::Message msg3;
            string out1, out2, out3;
            int ret;

            /* loop 1 */
            ret = msg1.from_str(sip_msg[i]);
            ASSERT_EQ(0, ret);

            msg1.to_str(out1);
    		//printf("\n\n%s\n", out1.c_str());

            /* loop 2 */
			ret = msg2.from_str(out1);
            ASSERT_EQ(0, ret);

			msg2.to_str(out2);
    		//printf("\n\n%s\n", out2.c_str());

            /* loop 3 */
			ret = msg3.from_str(out2);
            ASSERT_EQ(0, ret);

			msg3.to_str(out3);
    		//printf("\n\n%s\n", out3.c_str());

            /* compare two buffer */
            ASSERT_TRUE(out2 == out3);

            //printf("test sip enc/dec %d done\n", i);
        }
    }

    SUCCEED();
}

TEST(UtilTest, MysqlTest)
{
    Mysql helper("192.168.152.130", 9306, "test", "admin", "ad;43@ep|92.");

    u64 affected;
    ASSERT_EQ(0, helper.execute("delete from tb_test", affected));

    ASSERT_EQ(0, helper.execute("insert into tb_test values('atto')", affected));
	ASSERT_EQ(1, affected);

    ASSERT_EQ(0, helper.execute("insert into tb_test values('mike')", affected));
	ASSERT_EQ(1, affected);

    std::vector<string> ret1;
    ASSERT_EQ(0, helper.select_top("select * from tb_test", ret1));
	ASSERT_EQ(1, ret1.size());

    std::vector<std::vector<string>> ret2;
    ASSERT_EQ(0, helper.select("select * from tb_test", ret2));
	ASSERT_EQ(2, ret2.size());

    ASSERT_EQ(0, helper.execute("delete from tb_test", affected));
	ASSERT_EQ(ret2.size(), affected);

	SUCCEED();
}

int main(int argc, char *argv[])
{
    testing::InitGoogleTest(&argc, argv);
    int ret = RUN_ALL_TESTS();

	printf("gtest result: %d\n", ret);
	printf("press any key to continue...");
	getchar();
	return 0;
}

#endif //UTILTEST
